<template>
  <div>
    <el-row type="flex" justify="space-between" align="middle" class="topbar">
      <div class="logo">美食分享平台</div>
      <div class="search">
        <el-input v-model="keyword" placeholder="搜索分享或标签" clearable style="width: 480px" @keyup.enter.native="doSearch">
          <el-button slot="append" icon="el-icon-search" @click="doSearch"></el-button>
        </el-input>
      </div>
      <div class="user" v-if="me">
        <el-avatar :src="me.avatarUrl" size="small" style="cursor:pointer" @click.native="$router.push('/u/' + me.id)"></el-avatar>
        <span class="username" @click="$router.push('/u/' + me.id)">{{me.nickname || me.username}}</span>
        <el-button type="primary" size="small" round icon="el-icon-plus" @click="$router.push('/post/create')">发布</el-button>
      </div>
    </el-row>

    <!-- 搜索结果为空时的提示 -->
    <div v-if="list.length === 0 && keyword" class="empty-result">
      <el-empty description="搜索结果为空">
        <el-button type="primary" @click="clearSearch">返回首页</el-button>
      </el-empty>
    </div>

    <!-- 美食分享卡片列表（瀑布流布局） -->
    <div class="grid-wrap" v-else>
    <div class="masonry">
      <div class="masonry-item" v-for="item in list" :key="item.id">
        <el-card :body-style="{padding: '8px'}" class="post-card" @click.native="$router.push('/post/' + item.id)">
          <div class="cover-wrap">
            <img v-if="thumb[item.id]" :src="thumb[item.id]" class="cover" />
            <div v-else class="cover cover-empty">
              <i class="el-icon-picture-outline" />
            </div>
          </div>
          <div class="card-body">
            <el-tooltip :content="item.title" placement="top" :disabled="!item.title">
              <div class="title">{{ item.title }}</div>
            </el-tooltip>
            <div class="card-meta">
              <div class="meta-left">
                <i class="el-icon-user meta-icon"></i>
                <span class="meta-text" :title="getAuthorName(item)">{{ getAuthorName(item) }}</span>
              </div>
              <div class="meta-right">
                <i class="el-icon-time meta-icon"></i>
                <span class="meta-text" :title="formatTimeRaw(item)">{{ formatTime(item) }}</span>
              </div>
            </div>
            <!-- 预留：点赞按钮，可按需开启
            <div class="meta">
              <el-button
                :type="likedPosts[item.id] ? 'danger' : 'text'"
                :icon="likedPosts[item.id] ? 'el-icon-heart' : 'el-icon-heart-outline'"
                :class="{ 'liked-button': likedPosts[item.id] }"
                @click.stop="toggleLike(item)"
                size="mini"
                :title="likedPosts[item.id] ? '取消点赞' : '点赞'">
              </el-button>
            </div> -->
          </div>
        </el-card>
      </div>
    </div>
    </div>

    <!-- 无限滚动状态区和哨兵 -->
    <div ref="infiniteSentinel" style="height:1px"></div>
    <div class="infinite-status" v-if="list.length >= 0">
      <div v-if="loading" class="loading">
        <i class="el-icon-loading" style="margin-right:6px"></i>加载中...
      </div>
      <div v-else-if="loadError" class="error">
        加载失败：{{ loadError }}
        <el-button type="text" @click="retryLoad">重试</el-button>
      </div>
      <div v-else-if="finished" class="finished">没有更多了</div>
    </div>
  </div>
  </template>

<script>
import axios from 'axios'
export default {
  data () {
    return {
      list: [],
      total: 0,
      page: 1,
      size: 12,
      keyword: '',
      me: null,
      thumb: {},
      likedPosts: {}, // 存储点赞状态
      loading: false,
      finished: false,
      loadError: '',
      io: null
    }
  },
  created () {
    this.init()
  },
  mounted () {
    // 使用 IntersectionObserver 监听底部哨兵触底，触发加载更多
    const sentinel = this.$refs.infiniteSentinel
    if (sentinel && 'IntersectionObserver' in window) {
      this.io = new IntersectionObserver((entries) => {
        const entry = entries[0]
        if (entry && entry.isIntersecting) {
          this.loadMore()
        }
      }, { root: null, rootMargin: '0px', threshold: 0 })
      this.io.observe(sentinel)
    } else {
      // 兜底：监听 scroll
      window.addEventListener('scroll', this._onScroll, { passive: true })
    }
    // 首屏加载
    this.loadMore()
  },
  beforeDestroy () {
    if (this.io) {
      this.io.disconnect()
      this.io = null
    } else {
      window.removeEventListener('scroll', this._onScroll)
    }
  },
  methods: {
    async init () {
      try { const { data } = await axios.get('/api/user/me'); if (data.code === 1) this.me = data.data } catch (e) {}
    },
    _onScroll () {
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
      const winH = window.innerHeight || document.documentElement.clientHeight
      const docH = document.documentElement.scrollHeight || document.body.scrollHeight
      if (docH - (scrollTop + winH) < 80) {
        this.loadMore()
      }
    },
    getAuthorName (item) {
      // 优先展示更友好的昵称/用户名，做多重兜底，避免字段差异导致展示为空
      const user = item.user || item.author || {}
      return (
        item.authorName ||
        item.username ||
        item.publisherName ||
        user.nickname ||
        user.username ||
        user.name ||
        '匿名用户'
      )
    },
    formatTimeRaw (item) {
      // 返回原始时间字符串用于title
      return item.createTime || item.publishTime || item.gmtCreate || item.createdAt || item.create_at || ''
    },
    formatTime (item) {
      const raw = this.formatTimeRaw(item)
      if (!raw) return '未知时间'
      const d = new Date(raw)
      if (isNaN(d.getTime())) return raw
      const y = d.getFullYear()
      const m = String(d.getMonth() + 1).padStart(2, '0')
      const day = String(d.getDate()).padStart(2, '0')
      const hh = String(d.getHours()).padStart(2, '0')
      const mm = String(d.getMinutes()).padStart(2, '0')
      return `${y}-${m}-${day} ${hh}:${mm}`
    },
    async loadMore () {
      if (this.loading || this.finished) return
      this.loading = true
      this.loadError = ''
      try {
        const params = { page: this.page, size: this.size }
        if (this.keyword) params.q = this.keyword
        const { data } = await axios.get('/api/post/list', { params })
        if (data.code === 1) {
          const records = Array.isArray(data.data.records) ? data.data.records : []
          this.total = data.data.total || 0
          // 追加新数据
          const oldLen = this.list.length
          this.list = this.list.concat(records)

          // 为新增的帖子加载首图、点赞数与点赞状态
          const newSlice = this.list.slice(oldLen)
          await Promise.all(newSlice.map(async (p) => {
            try {
              const d = await axios.get('/api/post/' + p.id)
              if (d.data.code === 1 && d.data.data.images && d.data.data.images.length) {
                this.$set(this.thumb, p.id, d.data.data.images[0].url)
              }
            } catch (e) {}
            await this.loadPostLikeCount(p)
            await this.checkLikedStatus(p.id)
          }))

          // 翻到下一页
          this.page += 1
          // 结束条件：累计条数已达总数或本次返回为空
          if (this.list.length >= this.total || records.length === 0) {
            this.finished = true
          }
        } else {
          this.loadError = data.msg || '未知错误'
        }
      } catch (e) {
        this.loadError = e && e.message ? e.message : '网络错误'
      } finally {
        this.loading = false
      }
    },
    retryLoad () { this.loadMore() },
    async loadPostLikeCount (post) {
      try {
        const { data } = await axios.get(`/api/post/${post.id}/like-count`)
        if (data.code === 1) {
          post.likeCount = data.data.likeCount
        }
      } catch (error) {
        console.error(`获取帖子${post.id}点赞数失败:`, error)
      }
    },
    async checkLikedStatus (postId) {
      try {
        // 从后端接口检查是否已点赞
        const { data } = await axios.get(`/api/interact/is-liked/${postId}`)
        if (data.code === 1) {
          this.$set(this.likedPosts, postId, data.data.isLiked)
          // 同步更新本地缓存
          const key = 'liked:' + postId
          if (data.data.isLiked) {
            localStorage.setItem(key, '1')
          } else {
            localStorage.removeItem(key)
          }
        }
      } catch (error) {
        // 如果接口失败，使用本地缓存兜底
        console.error('检查点赞状态失败:', error)
        const key = 'liked:' + postId
        this.$set(this.likedPosts, postId, localStorage.getItem(key) === '1')
      }
    },
    async toggleLike (item) {
      const postId = item.id
      const key = 'liked:' + postId

      try {
        if (!this.likedPosts[postId]) {
          // 点赞
          const { data } = await axios.post('/api/interact/like/' + postId)
          if (data.code === 1) {
            this.$set(this.likedPosts, postId, true)
            localStorage.setItem(key, '1')
            // 重新获取最新的点赞数
            await this.loadPostLikeCount(item)
            this.$message.success('点赞成功')
          }
        } else {
          // 取消点赞
          const { data } = await axios.post('/api/interact/unlike/' + postId)
          if (data.code === 1) {
            this.$set(this.likedPosts, postId, false)
            localStorage.removeItem(key)
            // 重新获取最新的点赞数
            await this.loadPostLikeCount(item)
            this.$message.success('取消点赞')
          }
        }
      } catch (error) {
        this.$message.error('操作失败，请重试')
      }
    },
    doSearch () {
      // 重置并重新加载
      this.page = 1
      this.total = 0
      this.list = []
      this.thumb = {}
      this.likedPosts = {}
      this.finished = false
      this.loadError = ''
      this.loadMore()
    },
    clearSearch () {
      this.keyword = ''
      this.page = 1
      this.total = 0
      this.list = []
      this.thumb = {}
      this.likedPosts = {}
      this.finished = false
      this.loadError = ''
      this.loadMore()
    }
  }
}
</script>

<style scoped>

::global(body),
::global(html) {
  margin: 0;
  padding: 0;
}

::global(html),
::global(body),
::global(#app) {
  overflow-x: hidden; /* 仅隐藏水平滚动条 */
  overflow-y: auto;   /* 保留垂直滚动 */
}

.user {
  display: flex;
  align-items: center;
}

.user :deep(.el-avatar) {
  vertical-align: middle;
  margin-right: 8px;
}

.username {
  vertical-align: middle;
}
::deep(.el-row) {
  margin-top: 20px;
}
.topbar{
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 14px 20px;
  background: var(--color-card);
  border-bottom: 1px solid rgba(0,0,0,0.04);
  box-shadow: 0 4px 20px rgba(0,0,0,0.04);
  margin-top: 0;
}
.logo{ font-weight: 800; font-size: 20px; color: var(--color-accent); letter-spacing: .5px; }
.search :deep(.el-input__inner){ border-radius: 999px !important; background: #fff; border-color: rgba(0,0,0,0.06); padding: 0 14px; height: 36px; line-height: 36px; }
.search :deep(.el-input-group__append){ border-radius: 999px; overflow: hidden; }
.search :deep(.el-input-group__append .el-button){ background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.search :deep(.el-input-group__append .el-button:hover){ background: var(--color-primary-600); border-color: var(--color-primary-600); }
.username{ margin: 0 12px; cursor:pointer; color: var(--color-subtext); }
.title{ font-weight: 700; font-size: 15px; line-height: 1.5; max-height: 3.0em; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.meta{ color: var(--color-subtext); font-size:12px }

.liked-button {
  background-color: #ff4757 !important;
  border-color: #ff4757 !important;
  color: white !important;
}

.liked-button:hover {
  background-color: #ff3742 !important;
  border-color: #ff3742 !important;
}

.el-button--text.liked-button {
  background-color: transparent !important;
  border-color: transparent !important;
  color: #ff4757 !important;
}

.el-button--text.liked-button:hover {
  background-color: rgba(255, 71, 87, 0.1) !important;
  border-color: transparent !important;
}

.post-card { border-radius: var(--radius-md); overflow: hidden; transition: transform .25s ease, box-shadow .25s ease; box-shadow: var(--shadow-sm); }
.post-card:hover { transform: translateY(-3px) scale(1.01); box-shadow: var(--shadow-md); }

.cover-wrap{ position: relative; width: 100%; height: 190px; overflow: hidden; border-radius: 10px; background: #f5f7fa; }
.cover{ width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .35s ease; }
.post-card:hover .cover{ transform: scale(1.04); }
.cover-empty{ display:flex; align-items:center; justify-content:center; color:#c0c4cc; font-size:24px }
.card-body{ padding: 10px; }
.card-meta{ display:flex; align-items:center; justify-content:space-between; margin-top: 8px; color: var(--color-subtext); font-size:12px }
.meta-left, .meta-right{ display:flex; align-items:center; min-width: 0; }
.meta-icon{ margin-right: 4px; }
.meta-text{ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 140px; display: inline-block; }

.empty-result {
  margin: 40px 0;
  text-align: center;
}
.finished {
  text-align: center;
}
.loading {
  text-align: center;
}
.error {
  text-align: center;
}

.el-pagination :deep(.btn-prev:hover),
.el-pagination :deep(.btn-next:hover),
.el-pagination :deep(.el-pager li:hover){ color: var(--color-primary); }
.post-card {
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: transform .25s ease, box-shadow .25s ease;
  box-shadow: var(--shadow-sm);
  cursor: pointer; /* 添加这一行，设置鼠标样式为小手 */
}
.post-card:hover {
  transform: translateY(-3px) scale(1.01);
  box-shadow: var(--shadow-md);
}

.grid-wrap { /* 抵消 ElementUI el-row 的负外边距，避免横向溢出 */
  padding: 0 10px;
  max-width: 100%;
  overflow-x: hidden;
}

.masonry{ column-count: 4; column-gap: 16px; }
.masonry-item{ break-inside: avoid; margin-bottom: 16px; }

@media (max-width: 1400px){ .masonry{ column-count: 3 } }
@media (max-width: 1024px){ .masonry{ column-count: 2 } }
@media (max-width: 640px){ .masonry{ column-count: 1 } }

</style>
